package com.hqyj.springbootday03.config.shiro;

import com.hqyj.springbootday03.modules.account.service.UserService;
import com.hqyj.springbootday03.modules.account.entity.Resource;
import com.hqyj.springbootday03.modules.account.entity.Role;
import com.hqyj.springbootday03.modules.account.entity.User;
import com.hqyj.springbootday03.modules.account.service.ResourceService;
import com.hqyj.springbootday03.modules.account.service.RoleService;
import net.bytebuddy.build.Plugin;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * MyRealm
 */
@Component
public class MyRealm extends AuthorizingRealm {
	@Autowired
	private UserService userService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private ResourceService resourceService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo sai =  new SimpleAuthorizationInfo();

		User user = (User) principals.getPrimaryPrincipal();
		if (user == null) {
			return null;
		}

		List<Role> roles = roleService.getRolesByUserId(user.getId());
		roles.stream().forEach(roleItem -> {
			sai.addRole(roleItem.getRoleName());
			List<Resource> resources = resourceService.getResourcesByRoleId(roleItem.getId());
			resources.stream().forEach(resourceItem -> {
				sai.addStringPermission(resourceItem.getPermission());
			});
		});

		// 返回资源授权器
		return sai;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
			throws AuthenticationException {
		User user = userService.getUserByUserName((String) token.getPrincipal());
		if (user == null) {
			throw new UnknownAccountException("The account do not exist.");
		}

		// 返回身份验证器
		return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
	}
}
